﻿using jvm.rtda;
using jvm.rtda.frame;
using jvm.rtda.heap;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace jvm.native.java.lang
{
    class System
    {
        static string classname = "java/lang/System";
        public static void Init()
        {
            NativeMethodPool.Register(classname, "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V", arraycopy);
        }

        // public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
        // (Ljava/lang/Object;ILjava/lang/Object;II)V
        static void arraycopy(JFrame frame)
        {
            JLocalVars vars = frame.localVars;
            JObject src = vars.GetRef(0);
            int srcPos = vars.GetInt(1);
            JObject dest = vars.GetRef(2); 
            int destPos = vars.GetInt(3); 
            int length = vars.GetInt(4);

            if (src == null || dest == null)
            {
                Console.WriteLine("java.lang.NullPointerException");
                Environment.Exit(0);
            }
            if (!CheckArray(src, dest))
            {
                Console.WriteLine("java.lang.ArrayStoreException");
                Environment.Exit(0);
            }
            JObject.ArrayCopy(src, dest, srcPos, destPos, length);
        }

        static bool CheckArray(JObject src, JObject dest)
        {
            JClass srcClass = src.jClass;
            JClass destClass = dest.jClass;
            if (!srcClass.IsArray() || !destClass.IsArray())
            {
                return false;
            }
            if (srcClass.GetInnerClass().IsPrimitive() || destClass.GetInnerClass().IsPrimitive())
            {
                return srcClass.GetInnerClass() == destClass.GetInnerClass();
            }
            return true;
        }
    }
}
